home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Code Resources
/
icl8 LDEF 2.0
/
Source
/
icl8 LDEF.cpp
next >
Wrap
Text File
|
1995-11-14
|
12KB
|
396 lines
/*
Hiep's Special LDEF
Written by: Hiep Dam
Date: Long time ago (Dec 93?)
Public domain.
Previous incarnation as a pict list def, now a simple icon list def. Well,
not so simple. Each cell should contain the IconListData data; this list
def depends on each cell having at least this structure (you can extend it
if you want).
The IconListData structure basically notes how to hilite and frame the
cell (thus, each cell could be framed and/or hilited differently, though
this is NOT recommended!). It also contains the "icl8" rsrc id of the icon
you want to use. If you frame the cell, make sure you specify the frameWidth.
Also, if you cells are not 32x32 or 16x16 (std icon sizes) then you should
specify the iconSize.
Version History:
1.5 June 5 94: Changed from using PICTs to using icl8 icon families
2.0 Nov 14 95: Added ability to draw name as well, updated API and
drawing, selecting code. Pretty much complete overhaul.
Thanks to Steven Falkenburg & Norman Franke, whose simpler icon
LDEF source code structure made simplizing my code much easier.
*/
// ---------------------------------------------------------------------------
#include <Icons.h>
#include "icl8 LDEF.h"
enum {
kIconNameHeight = 10
};
// Used for kSelectbyFramingSpecial
enum {
kFrameHiliteRed = 39321, kFrameHiliteGreen = 52428, kFrameHiliteBlue = 65535,
kFrameTingeRed = 26214, kFrameTingeGreen = 26214, kFrameTingeBlue = 39321,
kFrameBodyRed = 48059, kFrameBodyGreen = 48059, kFrameBodyBlue = 48059,
kBlack = 0
};
// ---------------------------------------------------------------------------
static void CenterRect(Rect *innerRect, const Rect *outerRect);
static void GetIconDestRect(
const IconListDataPtr theIcon,
const Rect *cellRect,
Rect *destRect);
static void PlotIconName(
GrafPtr ownerPort,
const IconListDataPtr theIcon,
const Rect *iconRect,
const Rect *cellRect,
Rect *iconNameRect);
void DrawCell(
ListHandle listH,
const Rect *cellR,
Cell theCell,
short dataLen,
Boolean select);
// ---------------------------------------------------------------------------
void CenterRect(Rect *innerRect, const Rect *outerRect) {
short outerRectWidth = outerRect->right - outerRect->left;
short outerRectHeight = outerRect->bottom - outerRect->top;
short innerRectWidth = innerRect->right - innerRect->left;
short innerRectHeight = innerRect->bottom - innerRect->top;
short hDiff = (outerRectWidth - innerRectWidth) / 2;
short vDiff = (outerRectHeight - innerRectHeight) / 2;
innerRect->left = outerRect->left + hDiff;
innerRect->right = innerRect->left + innerRectWidth;
innerRect->top = outerRect->top + vDiff;
innerRect->bottom = innerRect->top + innerRectHeight;
} // END CenterRect
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
/*
Determine destination area to draw icon in (centered inside the cell rect).
If the icon specifies to draw the name as well, the dest area is moved up
a bit to accomodate the name.
*/
void GetIconDestRect(
const IconListDataPtr theIcon,
const Rect *cellRect,
Rect *destRect) {
short cellWidth = cellRect->right - cellRect->left;
short cellHeight = cellRect->bottom - cellRect->top;
short whatIconSize;
if (theIcon->iconSize != kIconBasedOnCellSize)
whatIconSize = theIcon->iconSize;
else if ((cellWidth > kIcon32Size) && (cellHeight > kIcon32Size))
whatIconSize = kIcon32Size;
else
whatIconSize = kIcon16Size;
switch(whatIconSize) {
case kIcon32Size:
// Explicitly use 32 pixel size
SetRect(destRect, 0, 0, kIcon32Size, kIcon32Size);
// Accomodate space for name
if (theIcon->drawName)
destRect->bottom += kIconNameHeight;
CenterRect(destRect, cellRect);
break;
case kIcon16Size:
// Explicitly use 16 pixel size
SetRect(destRect, 0, 0, kIcon16Size, kIcon16Size);
if (theIcon->drawName)
destRect->bottom += kIconNameHeight;
CenterRect(destRect, cellRect);
break;
}
if (theIcon->drawName) {
destRect->bottom -= kIconNameHeight;
}
} // END GetIconDestRect
// ---------------------------------------------------------------------------
/*
Draw the icon's name, based on the cell and icon rects. The name is
positioned centered and below the icon's rect.
The adjusted rect of the name is passed out to <iconNameRect> for later
hiliting if needed. If there is no name, an empty rect is passed.
*/
static void PlotIconName(
GrafPtr ownerPort,
const IconListDataPtr theIcon,
const Rect *iconRect,
const Rect *cellRect,
Rect *iconNameRect) {
short saveFont, saveFontSize, saveFontFace;
// Save current font, size, & face settings & set them to what we need to
saveFont = ownerPort->txFont;
saveFontSize = ownerPort->txSize;
saveFontFace = ownerPort->txFace;
TextFont(geneva);
TextSize(9);
TextFace(0);
// Get icon name
Str255 iconName;
Handle iconHandle;
short iconID;
ResType iconType;
iconHandle = GetResource('icl8', theIcon->id);
GetResInfo(iconHandle, &iconID, &iconType, iconName);
ReleaseResource(iconHandle);
// Center name
Rect nameRect;
if (iconName[0] == 0) {
SetRect(&nameRect, 0, 0, 0, 0);
}
else {
short nameWidth, cellWidth;
nameWidth = StringWidth(iconName);
cellWidth = cellRect->right - cellRect->left;
// Make sure name's width isn't longer than cell's; otherwise condense
if (nameWidth > cellWidth) {
TextFace(condense);
// Get width again (if still larger, clip it)
nameWidth = StringWidth(iconName);
if (nameWidth > cellWidth)
nameWidth = cellWidth;
}
SetRect(&nameRect, 0, 0, nameWidth, kIconNameHeight);
CenterRect(&nameRect, cellRect);
nameRect.top = iconRect->bottom;
nameRect.bottom = nameRect.top + kIconNameHeight;
// Draw it (finally...)
MoveTo(nameRect.left, nameRect.bottom);
DrawString(iconName);
InsetRect(&nameRect, -3, 0);
nameRect.bottom += 2;
}
TextFont(saveFont);
TextSize(saveFontSize);
TextFace(saveFontFace);
*iconNameRect = nameRect;
} // END PlotIconName
// ---------------------------------------------------------------------------
void DrawCell(
ListHandle listH,
const Rect *cellR,
Cell theCell,
short dataLen,
Boolean select) {
GrafPtr savePort;
PenState savePenState;
OSErr myErr;
IconListData theIcon;
Rect destRect;
Rect iconNameRect;
RgnHandle saveClip;
GetPort(&savePort);
SetPort((**listH).port);
saveClip = NewRgn();
GetClip(saveClip);
ClipRect(cellR); // Set clip region to cell rectangle, so no drawing outside cell
GetPenState(&savePenState);
PenNormal();
dataLen = sizeof(IconListData); // Only get enough stuff for our own purposes
LGetCell(&theIcon, &dataLen, theCell, listH);
// --------------------------------------------------
// STEP 1: Draw cell
// --------------------------------------------------
EraseRect(cellR);
GetIconDestRect(&theIcon, cellR, &destRect);
// Here's the actual call that'll do the work for us. Note that myErr is
// ignored by this LDEF.
myErr = PlotIconID(&destRect, atNone, ttNone, theIcon.id);
if (theIcon.drawName)
PlotIconName((**listH).port, &theIcon, &destRect, cellR, &iconNameRect);
// --------------------------------------------------
// STEP 2: Hilite cell and name accordingly (if need be)
// --------------------------------------------------
if (select) {
switch(theIcon.selType) {
case kSelectByInvertBW:
case kSelectByInvertHilite:
if (theIcon.selType == kSelectByInvertHilite)
LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
InvertRect(cellR);
break;
case kSelectByDarkenIcon:
myErr = PlotIconID(&destRect, atNone, ttSelected, theIcon.id);
// Hilite name
if (theIcon.drawName) {
LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
InvertRect(&iconNameRect);
}
break;
case kSelectByFramingBW:
// Frame cell by using a black border. Standard.
ForeColor(blackColor);
PenSize(theIcon.frameWidth, theIcon.frameWidth);
FrameRect(cellR);
break;
case kSelectbyFramingHilite:
// Frame the cell by using the hilite color the user chose in the
// General control panel. Note that this will work on a black and
// white mac, too
LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
PenSize(theIcon.frameWidth, theIcon.frameWidth);
PenMode(srcXor);
FrameRect(cellR);
break;
case kSelectByFramingSpecial:
// Use Special: frame by drawing a special, funky-looking frame
// that is copied after how the frame of a movable modal dialog looks.
// Everything is hard coded into this LDEF. You can change this if you
// wish. Note that it is up to the calling program to check if
// it's running on a Color QuickDraw mac. This code does not check
// whatsoever, so calling kUseSpecial on a black and white Mac will
// result in a crash.
RGBColor frameHilite, frameTinge, frameBody, frameBlack, foreSave;
Rect frameRect = *cellR;
frameBlack.red = frameBlack.green = frameBlack.blue = kBlack;
frameHilite.red = kFrameHiliteRed;
frameHilite.green = kFrameHiliteGreen;
frameHilite.blue = kFrameHiliteBlue;
frameTinge.red = kFrameTingeRed;
frameTinge.green = kFrameTingeGreen;
frameTinge.blue = kFrameTingeBlue;
frameBody.red = kFrameBodyRed;
frameBody.green = kFrameBodyGreen;
frameBody.blue = kFrameBodyBlue;
GetForeColor(&foreSave);
// Step 1: Draw outer black frame
RGBForeColor(&frameBlack);
FrameRect(&frameRect);
// Step 2: Draw outer upper left hilite
RGBForeColor(&frameHilite);
InsetRect(&frameRect, 1, 1); frameRect.right--; frameRect.bottom--;
// Top edge
MoveTo(frameRect.left, frameRect.top);
LineTo(frameRect.right - 1, frameRect.top);
// Left edge
MoveTo(frameRect.left, frameRect.top);
LineTo(frameRect.left, frameRect.bottom - 1);
// Step 3: Draw outer lower right tinge
RGBForeColor(&frameTinge);
// Right edge
MoveTo(frameRect.right, frameRect.bottom);
LineTo(frameRect.right, frameRect.top);
// Bottom edge
MoveTo(frameRect.right, frameRect.bottom);
LineTo(frameRect.left, frameRect.bottom);
// Step 4: Draw inner body frame
RGBForeColor(&frameBody);
InsetRect(&frameRect, 1, 1); frameRect.right++; frameRect.bottom++;
FrameRect(&frameRect);
// Step 5: Draw inner upper left tinge
RGBForeColor(&frameTinge);
InsetRect(&frameRect, 1, 1); frameRect.right--; frameRect.bottom--;
// Top edge
MoveTo(frameRect.left, frameRect.top);
LineTo(frameRect.right, frameRect.top);
// Left edge
MoveTo(frameRect.left, frameRect.top);
LineTo(frameRect.left, frameRect.bottom);
// Step 6: Draw inner lower right hilite
RGBForeColor(&frameHilite);
// Right edge
MoveTo(frameRect.right, frameRect.bottom);
LineTo(frameRect.right, frameRect.top - 1);
// Bottom edge
MoveTo(frameRect.right, frameRect.bottom);
LineTo(frameRect.left - 1, frameRect.bottom);
// Step 7: Draw inner black frame
RGBForeColor(&frameBlack);
InsetRect(&frameRect, 1, 1); frameRect.right++; frameRect.bottom++;
FrameRect(&frameRect);
RGBForeColor(&foreSave);
// Uncomment if you want this method to hilite the icon name as well
/*
if (theIcon.drawName) {
LMSetHiliteMode(LMGetHiliteMode() ^ (1 << hiliteBit));
InvertRect(&iconNameRect);
}
*/
break;
} // END switch
}
SetClip(saveClip);
SetPenState(&savePenState);
SetPort(savePort);
} // END DrawCell
// ---------------------------------------------------------------------------
#ifdef powerc
ProcInfoType __procinfo = uppListDefProcInfo;
#endif
pascal void main(short lMsg, Boolean lSelect, Rect *lRect, Cell lCell, short dataOffset,
short dataLen, ListHandle theList) {
switch(lMsg) {
case lDrawMsg:
case lHiliteMsg:
DrawCell(theList, lRect, lCell, dataLen, lSelect);
break;
default:
break;
} // END switch
} // END main entry point
// ---------------------------------------------------------------------------
// END icl8 LDEF.cpp